package org.example.Other;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
 * @Description: TODO
 * @Author: sats@jz
 * @Date: 2025/1/13 14:04
 **/
public class TrajectoryDrawingApp extends JFrame {
    private final int WIDTH = 400;
    private final int HEIGHT = 400;
    /*
     *距离
    */
    private final int MIN_DISTANCE = 30;
    /*
     * 角度
    */
    private final int MAX_JD = 20;
    /*
     * 产生点的信息
    */
    private List<Point> fixedPoints;
    /*
     * 用户轨迹
    */
    private List<Point> userTrajectory;
1.
    public TrajectoryDrawingApp() {
        setTitle("轨迹绘制，按照点绘制");
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);

        fixedPoints = generatePoints(4);
        userTrajectory = new ArrayList<>();

        DrawingPanel panel = new DrawingPanel();
        add(panel);

        setVisible(true);
    }

    private List<Point> generatePoints(int numPoints) {
        List<Point> points = new ArrayList<>();


        while (points.size() < numPoints) {
            Point newPoint = Point(points);
            if (isValidPoint(newPoint, points)) {
                points.add(newPoint);
            }
        }
        System.out.println("产生点的信息： " + points);
        return points;
    }
    /* 根据已经产生的点
     * 缩小随机数范围， 待续
    */
    private Point Point(List<Point> pointList){
        Random random = new Random();
        return new Point(random.nextInt(WIDTH), random.nextInt(HEIGHT));
    }



    private boolean isValidPoint(Point point, List<Point> points) {
        // 距离
        for (Point p : points) {
            if (point.distance(p) < MIN_DISTANCE) {
                return false;
            }
        }
        // 角度
        if (points.size() >= 2) {
            Point p1 = points.get(points.size() - 2);
            Point p2 = points.get(points.size() - 1);

            double angle = calculateAngle(p1, p2, point);
            if (Math.abs(angle - 180) < MAX_JD) {
                return false;
            }
        }


        return true;
    }

    /*
     * 计算三个点的角度
     * 向量p2,p1
     * 向量p3,p2
     * 注意传点先后顺序
    */
    private static double calculateAngle(Point p1, Point p2, Point p3) {

        double v1x = p2.x - p1.x, v1y = p2.y - p1.y;
        double v2x = p3.x - p2.x, v2y = p3.y - p2.y;


        double dotProduct = v1x * v2x + v1y * v2y;
        double mag1 = Math.sqrt(v1x * v1x + v1y * v1y);
        double mag2 = Math.sqrt(v2x * v2x + v2y * v2y);


        return Math.toDegrees(Math.acos(dotProduct / (mag1 * mag2)));
    }

    private class DrawingPanel extends JPanel {
        public DrawingPanel() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    userTrajectory.clear();
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    System.out.println("鼠标轨迹：");
                    for (Point p : userTrajectory) {
                        System.out.println("(" + p.x + ", " + p.y + ")");
                    }
                }
            });

            addMouseMotionListener(new MouseMotionAdapter() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    userTrajectory.add(e.getPoint());
                    repaint();
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            // 产生的点
            g.setColor(Color.RED);
            for (int i = 0; i < fixedPoints.size(); i++) {
                Point p = fixedPoints.get(i);
                g.fillOval(p.x - 5, p.y - 5, 10, 10);

//                int labelX = Math.min(p.x + 10, WIDTH - 30); // 文字右边界离画布边缘留出空间
//                int labelY = Math.max(p.y, 10);

                g.drawString("P" + (i + 1), p.x + 10, p.y);
            }

            // 鼠标
            g.setColor(Color.BLUE);
            for (int i = 1; i < userTrajectory.size(); i++) {
                Point p1 = userTrajectory.get(i - 1);
                Point p2 = userTrajectory.get(i);
                g.drawLine(p1.x, p1.y, p2.x, p2.y);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TrajectoryDrawingApp::new);
    }
}
